use anyhow::{Context, Result};
use futures::StreamExt;
use indicatif::{ProgressBar, ProgressStyle};
use reqwest::Client;
use std::fs::File;
use std::io::Write;
use console::style;

pub async fn download_file(url: &str, output_path: &str) -> Result<()> {
    let client = Client::new();
    let response = client.get(url)
        .send()
        .await
        .context(format!("{} 使用链接[{}]获取下载失败!", style("❌").red(),url))?;

    let total_size = response.content_length()
        .context("❌ 获取文件大小失败!")?;

    let pb = ProgressBar::new(total_size);
    pb.set_style(ProgressStyle::default_bar()
        .template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})")?
        .progress_chars("#>-"));

    let mut file = File::create(output_path)
        .context("❌ 创建文件失败!")?;
    println!("{} 创建文件[{}]成功! 启动下载...", style("✅").green(), output_path);

    let mut downloaded: u64 = 0;
    let mut stream = response.bytes_stream();

    while let Some(chunk) = stream.next().await {
        let chunk = chunk.context("❌ 下载文件中断!")?;
        file.write_all(&chunk)
            .context("❌ 等待文件写入超时!")?;
        downloaded += chunk.len() as u64;
        pb.set_position(downloaded);
    }

    pb.finish_with_message("✅ 文下载完成!");

    println!("{} 文件[{}]下载成功! 退出下载...",style("✅").green(), output_path);

    Ok(())
}